"""
title: Open WebUI 0.6 Pipeline - AI Agent Generate PowerPoint
author: Gou Feng
date: 2024-06-01
version: 1.0
license: MIT
description: 将用户消息转发给生成 PowerPoint (python-pptx) 的模型处理
requirements: requests
"""

import json
import time
import requests
from typing import List, Optional
from pydantic import BaseModel
# from schemas import OpenAIChatMessage

class Pipeline:
    
    # 配置类 - 定义过滤器的连接目标和优先级
    class Valves(BaseModel):
        
        # 作用目标管道 (默认作用于 llama3:latest 模型)
        # 格式说明: ["*"] 表示作用于所有模型, ["model1", "model2"] 指定特定模型
        pipelines: List[str] = ["qwen2.5-coder:7b"]
        
        # 执行优先级 (数值越小越先执行)
        priority: int = 0

    def __init__(self):
        
        # 初始化过滤器属性
        self.type = "filter"                     # 声明为过滤器类型
        self.name = "AI Agent - 生成 PowerPoint" # 中文展示名称
        self.valves = self.Valves()              # 加载配置参数
        
        self.SYSTEM_PROMPT = """[SYSTEM]

你是一名智能助手, 你正处在智能工作流中的最后一环。
由于你是用户的交互入口, 用户看不见智能工作流中其它智能助手输出的信息。
你的任务是将前一位智能助手输出的内容展现给用户。
在 [CONTEXT] 中将包含前一位智能助手输出的内容, 你将把 [CONTEXT] 中的内容进行适当美化并输出给用户。

-------------------- 任务示例 (Task Example):

[CONTEXT]

以下是 working 数据库中查询到的数据表:

    [
        {"Tables_in_working": "table_0"},
        {"Tables_in_working": "table_1"},
        {"Tables_in_working": "table_2"}
    ]

你的输出:

以下是 working 数据库中查询到的数据表:

| Tables_in_working |
|:------------------|
|           table_0 |
|           table_1 |
|           table_2 |

-------------------- 任务开始 (Task Start):

[CONTEXT]

::CONTEXT::

        """

    # 生命周期钩子函数
    async def on_startup(self):
        """服务器启动时触发 (可初始化资源)"""
        print(f"[{self.name}] 过滤器启动")

    async def on_shutdown(self):
        """服务器关闭时触发 (可清理资源)"""
        print(f"[{self.name}] 过滤器关闭")

    def GF_Python_3_Requests_2_POST_JSON(self, Args:list) -> dict:
    
        # Requirement: requests 2.x.x / json (Python 3.12.0)
    
        URL = "http://127.0.0.1:5000/api/ai-agent-office-ppt"
        # ..........................................
        Headers   = {"Content-Type": "application/json"}
        JSON_Data = {"args": Args} # Like: "args": ["有哪些可用的 PPT 模板?", "/www/html/resource/example.pptx"]
        response  = requests.post(URL, headers=Headers, json=JSON_Data)
        # ..........................................
        Response_Dict = json.loads(response.text) # JSON 字符串转字典 (Dict)
        # ..........................................
        return Response_Dict

    # 核心处理逻辑
    async def inlet(self, body: dict, user: Optional[dict] = None) -> dict:
        """
        处理请求数据的主入口
        :param body: 包含消息列表的请求体 (格式: {"messages": [...]})
        :param user: 用户信息 (可选)
        :return: 修改后的请求体
        """
        # 遍历所有消息 (原始数据格式为字典列表)
        for message in body.get("messages", []):
            
            # 仅处理用户消息 (role == "user")
            if message.get("role") == "user":
            
                original_content = message.get("content", "") # 提取原始消息内容
            
                if (("PPT" in original_content) and ("生成" in original_content)):
                
                    PPT_Save_Path = "/www/html/resource/example.pptx"
                    # ..............................
                    Workflow_Response_Dict = self.GF_Python_3_Requests_2_POST_JSON([original_content, PPT_Save_Path])
                    Workflow_Content       = Workflow_Response_Dict["content"]
                    # ..............................
                    COMPLETE_PROMPT = self.SYSTEM_PROMPT
                    COMPLETE_PROMPT = COMPLETE_PROMPT.replace("::CONTEXT::", Workflow_Content)
                    COMPLETE_PROMPT = COMPLETE_PROMPT.replace("/www/html/resource/", "http://10.47.167.233:8090/resource/")

                    modified_content = COMPLETE_PROMPT

                    message["content"] = modified_content
                
                # 调试日志 (实际使用可注释掉)
                print(f"[{self.name}] 已修改用户消息: {modified_content[:50]}...")
        
        # 返回修改后的完整请求体
        return body

# EOF Signed by GF.
